package net.ssta.util.bill;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.Date;

import javax.servlet.http.HttpServletRequest;
import javax.sql.DataSource;

import net.ssta.common.DataBaseConfig;
import net.ssta.core.base.BaseException;
import net.ssta.core.db.DBConnectionProvider;
import net.ssta.core.db.Record;
import net.ssta.core.db.RecordSet;
import net.ssta.util.bill.chargeobj.ChargeInterface;

import org.apache.log4j.Logger;

import com.yztc.rc.api.framework.Context;
import com.yztc.rc.api.framework.ContextFactory;
import com.yztc.rc.api.framework.entity.UserAccount;
import com.yztc.rc.api.framework.manager.UserManager;

/**
 * 用户积分
 * @author Administrator
 *
 */

public class UserPoint {
	private static Logger log = Logger.getLogger(UserPoint.class.getClass()); 
	private String userId;
	private int userPoint;
	private Date startDate;
	private Date endDate;
	private String CID;//主键
	public static String jndiName="jdbc/SSTA";
	
	/**
	 * 构造函数，通过用户ID来查找
	 * @param userId
	 */
	public UserPoint(String userId)throws SQLException{
		RecordSet rs=null;
		Connection conn = null;
    	try {
    		conn = DBConnectionProvider.getConnection(jndiName);
	    	Record r=new Record();
	    	r.setConnection(conn);
	    	r.setEntityName("T_USER_POINT");
	    	r.setPrimaryKey("USERID");
	    	r.addData("USERID",userId);
	    	r=r.findByPrimaryKey();
	    	if(r==null){
	    		r=new Record();
	    	}
	    	initUserPoint(r);
	    	this.userId=userId;
		} catch (SQLException e) {
			log.error("根据用户ID查找用户分数出错："+e); 
			throw e;
		}finally{
			try{
				if(conn != null) conn.close();
			}catch (SQLException e){
				 log.error("关闭conn出错",e);
			}
		}
    	 
	}
	 
	public static UserPoint getUserPointByUserAccount(String userName)throws SQLException,Exception{
		UserPoint up=null;
		try{
			DataSource ds=DataBaseConfig.getFrameworkDataSource();
			UserManager um=UserManager.getInstance(ds);
			UserAccount au=um.getUserAccountByLoginName(userName);
			String userId=au.getUserId();
			up=new UserPoint(userId);
		} catch (SQLException e) {
			throw e;
		}catch (Exception ee) {
			throw ee;
		}
		return up;
	}

	
	private void initUserPoint(Record r){
		this.userId=r.getString("USERID");
		this.startDate=r.getDate("STARTDATE");
		this.endDate=r.getDate("ENDDATE");
		this.userPoint=r.getInt("USERPOINT");
		this.CID=r.getString("CID");
	}
	
	
	
	/**
	 * 通过支付宝充值
	 * @param money
	 * @param OperatorId 操作者ID
	 */
	public void rechargeAlipay(int money,Connection conn)throws SQLException,Exception{
		
		 
		UserBill bill=new UserBill();
		try{
			if(this.CID==null||this.CID.equals("")){//如果是空，则增加，如果不是，则更新
		    	Record r=new Record();
		    	r.setConnection(conn);
		    	r.setEntityName("T_USER_POINT");
		    	r.setPrimaryKey("CID");
		    	r.addData("USERID",this.userId);
		    	r.addData("USERPOINT",money);
		    	bill.setRemain(money);
		    	r.create();
			}else{
				conn = DBConnectionProvider.getConnection(jndiName);
		    	Record r=new Record();
		    	r.setConnection(conn);
		    	r.setEntityName("T_USER_POINT");
		    	r.setPrimaryKey("CID");
		    	r.addData("CID",this.CID);
		    	r.addData("USERID",this.userId);
		    	r.addData("USERPOINT",this.userPoint+money);
		    	bill.setRemain(this.userPoint+money);
		    	r.update();
			}
			
			
			bill.setCostNumber(money);
			bill.setCostUserName(this.userId);
			bill.setCType("alipay");
			bill.setCostTime(new Date());
			this.createBill(bill);
		} catch (SQLException e) {
			log.error("根据用户ID充值用户分数出错："+e); 
			throw e;
		} 
	}
	
	
	
	/**
	 * 充值
	 * @param money
	 * @param OperatorId 操作者ID
	 */
	public void recharge(int money,String operatorId,String ipAddress,String mark)throws SQLException,Exception{
		
		Connection conn=null;
		UserBill bill=new UserBill();
		try{
			if(this.CID==null||this.CID.equals("")){//如果是空，则增加，如果不是，则更新
				conn = DBConnectionProvider.getConnection(jndiName);
		    	Record r=new Record();
		    	r.setConnection(conn);
		    	r.setEntityName("T_USER_POINT");
		    	r.setPrimaryKey("CID");
		    	r.addData("USERID",this.userId);
		    	r.addData("USERPOINT",money);
		    	bill.setRemain(money);
		    	r.create();
			}else{
				conn = DBConnectionProvider.getConnection(jndiName);
		    	Record r=new Record();
		    	r.setConnection(conn);
		    	r.setEntityName("T_USER_POINT");
		    	r.setPrimaryKey("CID");
		    	r.addData("CID",this.CID);
		    	r.addData("USERID",this.userId);
		    	r.addData("USERPOINT",this.userPoint+money);
		    	bill.setRemain(this.userPoint+money);
		    	r.update();
			}
			
			
			bill.setCostNumber(money);
			bill.setCostUserName(this.userId);
			bill.setCType("recharge");
			bill.setCostTime(new Date());
			bill.setOperatorId(operatorId);
			bill.setCostIp(ipAddress);
			bill.setMark(mark);
			
			this.createBill(bill);
		} catch (SQLException e) {
			log.error("根据用户ID充值用户分数出错："+e); 
			throw e;
		}finally{
			try{
				if(conn != null) conn.close();
			}catch (SQLException e){
				 log.error("关闭conn出错",e);
			}
		}
	}
	
	
	
	/**
	 * 扣除费用
	 * @param bill
	 * @throws UserBillException
	 */ 
	public void chargeBack(int money,String operatorId,String ipAddress,String mark) throws UserBillException,SQLException{
		Connection conn=null;
		UserBill bill=new UserBill();
		try{
			if(this.CID==null||this.CID.equals("")){//如果是空，则增加，如果不是，则更新
				conn = DBConnectionProvider.getConnection(jndiName);
		    	Record r=new Record();
		    	r.setConnection(conn);
		    	r.setEntityName("T_USER_POINT");
		    	r.setPrimaryKey("CID");
		    	r.addData("USERID",this.userId);
		    	r.addData("USERPOINT",0);
		    	bill.setRemain(0);
		    	r.create();
			}else{//如果分数小于要扣除的分数，则扣分至0
				if(this.userPoint<money){
					minusPoint(userPoint);
					bill.setRemain(0);
				}else{
					minusPoint(money);
					bill.setRemain(this.userPoint-money);
				}
				
			}
			
			
			bill.setCostNumber(money);
			bill.setCostUserName(this.userId);
			bill.setCType("chargeBack");
			bill.setCostTime(new Date());
			bill.setOperatorId(operatorId);
			bill.setCostIp(ipAddress);
			bill.setMark(mark);
			this.createBill(bill);
			
		} catch (SQLException e) {
			log.error("扣除用户分数出错："+e); 
			throw e;
		}finally{
			try{
				if(conn != null) conn.close();
			}catch (SQLException e){
				 log.error("关闭conn出错",e);
			}
		}
	}
	
	
	/**
	 * 统包管理
	 * @param bill
	 * @throws UserBillException
	 */ 
	public void vipConfig(Date startDate,Date endDate,String operatorId,String ipAddress,int minusPoint) throws UserBillException,SQLException{
		Connection conn=null;
		UserBill bill=new UserBill();
		try{
			conn = DBConnectionProvider.getConnection(jndiName);
	    	Record r=new Record();
	    	r.setConnection(conn);
	    	r.setEntityName("T_USER_POINT");
	    	r.setPrimaryKey("CID");
	    	r.addData("USERID",this.userId);
	    	r.addData("STARTDATE",startDate);
	    	r.addData("ENDDATE",endDate);
	    	r.addData("USERPOINT",this.userPoint-minusPoint);
			if(this.CID==null||this.CID.equals("")){//如果是空，则增加，如果不是，则更新
		    	r.create();
			}else{
				r.addData("CID",this.CID);
				r.update();
			}
			
			
			bill.setCostUserName(this.userId);
			bill.setCType("vip");
			bill.setCostTime(new Date());
			bill.setOperatorId(operatorId);
			bill.setCostIp(ipAddress);
			bill.setStartDate(startDate);
			bill.setEndDate(endDate);
			bill.setRemain(this.userPoint-minusPoint);
			this.createBill(bill);
			
		} catch (SQLException e) {
			log.error("扣除用户分数出错："+e); 
			throw e;
		}finally{
			try{
				if(conn != null) conn.close();
			}catch (SQLException e){
				 log.error("关闭conn出错",e);
			}
		}
	}
	
	
	/**
	 * 为阅读文章扣除费用
	 * @param bill
	 * @throws UserBillException
	 */ 
	public void charge(ChargeInterface chargeObj,UserBill bill) throws UserBillException,SQLException{
		if(bill==null){
			throw new RuntimeException("在扣费时，UserBill为null");
		}
		
		
		 int costNum=chargeObj.calCostNumber();
		 if(costNum==0){//如果积分为0，则返回
			 return;
		 }
		 if(this.userPoint<costNum){
			 log.error("用户积分小于需要扣除的积分："); 
			 throw new UserBillException(UserBillException.pointNotEnough,"用户积分小于需要扣除的积分\n"+bill.getCostUserName()+":"+this.userPoint+"\n"+bill.getChannelId()+":"+costNum);
		 }
		 bill=chargeObj.initBill(bill);
		 if(!hasReadInfo(this.userId,bill.getInfoId())&&!isVip()){//如果不是统包用户
			 minusPoint(costNum);
			 bill.setCostUserName(this.userId);
			 bill.setCostNumber(costNum);
			 bill.setRemain(this.userPoint-costNum);
			 createBill(bill);//存储账单
		 }
	}
	
	/**
	 * 判断此用户是否读过文章
	 * @param userId
	 * @param infoId
	 * @return
	 * @throws SQLException
	 */
	public static boolean hasReadInfo(String userId,String infoId)throws SQLException{
		boolean flag=true; 
		Connection conn = null;
    	try {
    		conn = DBConnectionProvider.getConnection(jndiName);
	    	Record r=new Record();
	    	r.setConnection(conn);
	    	r.setEntityName("T_USER_BILL");
	    	r.addPrimaryKey("COSTUSERNAME");
	    	r.addPrimaryKey("INFOID");
	    	r.addData("COSTUSERNAME",userId);
	    	r.addData("INFOID",infoId);
	    	r=r.findByPrimaryKey();
	    	if(r==null){
	    		flag=false;
	    	}
	     
		} catch (SQLException e) {
			log.error("查找用户以前是否阅读过此文章："+e); 
			throw e;
		}finally{
			try{
				if(conn != null) conn.close();
			}catch (SQLException e){
				 log.error("关闭conn出错",e);
			}
		}
		return flag;
	}
	
	protected void createBill(UserBill bill)throws SQLException{
		Connection conn = null;
    	try {
    		conn = DBConnectionProvider.getConnection(UserPoint.jndiName);
	    	Record r=new Record();
	    	r.setConnection(conn);
	    	r.setEntityName("T_USER_BILL");
	    	r.setPrimaryKey("BILLID");
	    	r.addData("COSTIP",bill.getCostIp());
	    	r.addData("COSTUSERNAME",bill.getCostUserName());
	    	r.addData("COST",bill.getCostNumber());
	    	r.addData("CTYPE",bill.getCType());
	    	r.addData("COSTTIME",bill.getCostTime());
	    	r.addData("CHANNELID",bill.getChannelId());
	    	r.addData("INFOID",bill.getInfoId());
	    	r.addData("STARTDATE",bill.getStartDate());
	    	r.addData("ENDDATE",bill.getEndDate());
	    	r.addData("TITLE",bill.getTitle());
	    	r.addData("MARK",bill.getMark());
	    	r.addData("REMAINPONINT",bill.getRemain());
	    	String operator="";
	    	try{
		    	UserAccount uac=null;
		    	Context context=ContextFactory.getContext();
		    	if(context!=null){
		    		uac=context.getUserAccount();
		    		operator=uac.getUserId();
		    	}
	    	}catch(Exception e){}
	    	r.addData("OPERATOR",operator);
	    	r.create();
	    	
		} catch (SQLException e) {
			log.error("存储账单出错："+e); 
			throw e;
		}finally{
			try{
				if(conn != null) conn.close();
			}catch (SQLException e){
				 log.error("关闭conn出错",e);
			}
		}
		
	}
	
	

	/**
	 *   
	 * @return
	 * @throws SQLException
	 */
	public static RecordSet getIpConfig(String userId) throws SQLException ,BaseException,Exception{
		Connection conn=null;
		RecordSet rs=null;
		try{
			conn= DBConnectionProvider.getConnection(UserPoint.jndiName);
			Record r=new Record();
			r.setConnection(conn);
			r.addData("USERID",userId);
			r.setPrimaryKey("USERID");
			r.setEntityName("T_USER_IPCONFIG");
		    rs=r.find();
		} catch (SQLException e) {
			log.error("得到用户的IP设置："+e);
			throw e;
		}catch (Exception e) {
			log.error("得到用户的IP设置："+e);
			throw e;
		}finally{
			try{
				if(conn != null) conn.close();
			}catch (SQLException e){
				 log.error("关闭conn出错",e);
			}
		}
		return rs;
	}
	
	/**
	 * 判断是否是统包用户，且当前时间在统包区间内
	 * @return
	 */
	public boolean isVip(){
		Date date=new Date();
		if(this.endDate==null||this.startDate==null){
			return false;
		}
		if(date.before(this.endDate)&&date.after(this.startDate)){
			return true;
		}
		return false;
	}
	
	
	
	/**
	 * 判断是否是统包用户，且当前IP在许可范围内
	 * @return
	 */
	public static boolean isInIpRange(String userId,HttpServletRequest request){
		try{
		String ipAddress=request.getRemoteAddr();
		RecordSet rs=getIpConfig(userId);
		if(rs==null||rs.size()<1){//如果没有IP限制，则返回true
			return true;
		}
		
		for(int i=0;i<rs.size();i++){
			String ip=rs.get(i).getString("IP","");
			String ipend=rs.get(i).getString("IPEND","");
			if("".equals(ipend)){
				if(ip.equals(ipAddress)){
					return true;
				}
			}else{
				String ipPix=ip.substring(0,ip.lastIndexOf('.'));
				String ipEndPix=ipend.substring(0,ipend.lastIndexOf('.'));
				String ipAddressPix=ipAddress.substring(0,ipAddress.lastIndexOf('.'));
				if(ipAddressPix.equals(ipPix)&&ipAddressPix.equals(ipEndPix)){//前三部分相等
					int ipLast=Integer.parseInt(ip.substring(ip.lastIndexOf('.')+1,ip.length()));
					int ipEndLast=Integer.parseInt(ipend.substring(ipend.lastIndexOf('.')+1,ipend.length()));
					int ipAddressLast=Integer.parseInt(ipAddress.substring(ipAddress.lastIndexOf('.')+1,ipAddress.length()));
					if(ipLast<=ipAddressLast&&ipEndLast>=ipAddressLast){//后一部分，在开始和结束之间
						return true;
					}
				}
			}
			
			
		}
		
		
		} catch (SQLException e) {
			log.error("计算用户当前IP是否在许可范围内："+e); 
		} catch (Exception e) {
			log.error("计算用户当前IP是否在许可范围内："+e); 
		} 
		return false;
	}
	
	/**
	 * 
	 * @param cosNum
	 * @throws SQLException
	 */
	private void minusPoint(int cosNum) throws SQLException {
		Connection conn = null;
    	try {
    		conn = DBConnectionProvider.getConnection(jndiName);
	    	Record r=new Record();
	    	r.setConnection(conn);
	    	r.setEntityName("T_USER_POINT");
	    	r.setPrimaryKey("USERID");
	    	r.addData("USERID",userId);
	    	r.addData("USERPOINT",this.userPoint-cosNum);
	    	r.update();
		} catch (SQLException e) {
			log.error("扣除用户分数出错："+e); 
			throw e;
		}finally{
			try{
				if(conn != null) conn.close();
			}catch (SQLException e){
				 log.error("关闭conn出错",e);
			}
		}
	}
	 
	 
	
	/**
	 * @return the userId
	 */
	public String getUserId() {
		return userId;
	}

	/**
	 * @param userId the userId to set
	 */
	public void setUserId(String userId) {
		this.userId = userId;
	}

 

	/**
	 * @return the userPoint
	 */
	public int getUserPoint() {
		return userPoint;
	}

	/**
	 * @param userPoint the userPoint to set
	 */
	public void setUserPoint(int userPoint) {
		this.userPoint = userPoint;
	}

	/**
	 * @return the startDate
	 */
	public Date getStartDate() {
		return startDate;
	}

	/**
	 * @param startDate the startDate to set
	 */
	public void setStartDate(Date startDate) {
		this.startDate = startDate;
	}

	/**
	 * @return the endDate
	 */
	public Date getEndDate() {
		return endDate;
	}

	/**
	 * @param endDate the endDate to set
	 */
	public void setEndDate(Date endDate) {
		this.endDate = endDate;
	}
}
